
public class IRCCommandEvaluator {
	
	private IRCClient client;
	private boolean DEBUG = true;
	
	public IRCCommandEvaluator(IRCClient client) {
		this.client = client;
	}
	
	public void evaluation(IRCCommand cmd) {
		if (cmd.isNumeric()) {
			evalNumeric(cmd);
		}
		else{
			evalStringCommand(cmd);
		}
		if (DEBUG){
			client.printToSys(cmd.getString());
		}
	}
	
	private void evalNumeric(IRCCommand cmd) {
		switch (cmd.getNumCommand()) {
		
		case 1:
		case 2:
		case 3:
		case 4:
		case 20:
			client.printToSys(formatWelcome(cmd));
			break;
		
		case 5:
			//bounce
			client.printToSys(formatWelcome(cmd));
			//client.disconnect();
			break;
		case 311:
			handle311(cmd);
			break;
		case 312:
			handle312(cmd);
			break;
		case 313:
			handle313(cmd);
			break;
		case 317:
			handle317(cmd);
			break;
		case 318:
			handle318(cmd);
			break;
		case 319:
			handle319(cmd);
			break;
		case 353:
			handleNamelist(cmd);
			break;
		case 366:
			//end of name list
			break;
		case 331:
			//no topic
			break;
		case 332:
			handle332(cmd);
			break;
		case 333:
			//creator of topic on join
			break;
		case 433:
			handle433(cmd);
			client.disconnect();
			break;
		default:
			handleDefNum(cmd);
			break;
		}
		
	}
	
	private void evalStringCommand(IRCCommand cmd) {
		if (cmd.getCommand().equalsIgnoreCase("privmsg")){
			handlePrivmsg(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("ping")){
			handlePing(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("JOIN")){
			handleJoin(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("part")){
			handlePart(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("quit")){
			handleQuit(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("nick")){
			handleNick(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("kick")){
			handleKick(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("topic")){
			handleTopic(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("notice")){
			handleNotice(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("whois")){
			handleWhois(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("pong")){
			handlePong(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("away")){
			handleAway(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("mode")){
			handleMode(cmd);
		}else if (cmd.getCommand().equalsIgnoreCase("error")){
			handleError(cmd);
		}else{
			handleUnknown(cmd);
		}
	}
	
	private void handleError(IRCCommand cmd) {
		client.disconnect();	
	}

	private void handleMode(IRCCommand cmd) {
		client.printToChannel(cmd.getParameter(0), formatMode(cmd));
		parseMode(cmd);
	}
	
	private void handleUnknown(IRCCommand cmd) {
		client.printToSys(formatNotification("Unknown command: " + cmd.getString()));
	}

	private void handleAway(IRCCommand cmd) {
		//Don't think that a server ever sends this command to user.
		client.printToSys("unsure implementation on AWAY " + cmd.getString());
	}

	private void handlePong(IRCCommand cmd) {
		client.printToSys(formatNotification("Pong: " + cmd.getPrefix()));
	}

	private void handleWhois(IRCCommand cmd) {
		//Don't think that a server ever sends this command to user.
		client.printToSys("unsure implementation on WHOIS " + cmd.getString());
	}

	private void handleNotice(IRCCommand cmd) {
		client.printToSys("(" + cmd.getCommand() + ")" + cmd.getParameter(1));
	}

	private void handleTopic(IRCCommand cmd) {
		client.setTopic(cmd.getParameter(0), cmd.getParameter(1));
		client.printToChannel(cmd.getParameter(0), formatTopic(cmd));
	}
	
	private void handle332(IRCCommand cmd) {
		client.setTopic(cmd.getParameter(1), cmd.getParameter(2));
		client.printToChannel(cmd.getParameter(1), format332(cmd));
	}
	
	private void handle311(IRCCommand cmd) {
		client.printToPrivmsg(cmd.getParameter(1), format311(cmd));
	}
	
	private String format311(IRCCommand cmd) {
		return cmd.getParameter(1) + " is " + cmd.getParameter(2) + "@" + cmd.getParameter(3)
			   + " " + cmd.getParameter(4) + " " + cmd.getParameter(5);
	}
	
	private void handle312(IRCCommand cmd) {
		client.printToPrivmsg(cmd.getParameter(1), format312(cmd));
	}
	
	private String format312(IRCCommand cmd) {
		return cmd.getParameter(1) + " is on " + cmd.getParameter(2) + " : " + cmd.getParameter(3);
	}
	
	private void handle313(IRCCommand cmd) {
		client.printToPrivmsg(cmd.getParameter(1), cmd.getParameter(1) + " is IRC op.");
	}
	
	private void handle317(IRCCommand cmd) {
		client.printToPrivmsg(cmd.getParameter(1), cmd.getParameter(1) + " has been idle for " +
				cmd.getParameter(2));
	}
	
	private void handle318(IRCCommand cmd) {
		
	}
	
	private void handle319(IRCCommand cmd) {
		client.printToPrivmsg(cmd.getParameter(1), cmd.getParameter(1) + " is in " + 
				cmd.getParameter(2));
	}
	
	private void handle433(IRCCommand cmd) {
		client.printToSys(cmd.getParameter(1) + cmd.getParameter(2));
	}
	
	private void handleDefNum(IRCCommand cmd) {
		client.printToSys(cmd.getCommand() + ": " +  cmd.getParameter(1));
	}

	private void handleKick(IRCCommand cmd) {
		client.removeUser(cmd.getParameter(0), cmd.getParameter(1));
		client.printToChannel(cmd.getParameter(0), formatKick(cmd));
	}

	private void handleNick(IRCCommand cmd) {
		client.changeUser(cmd.getNick(), cmd.getParameter(0));
	}

	private void handleQuit(IRCCommand cmd) {
		client.removeUser(cmd.getNick());
		client.printToSys(formatQuit(cmd));
	}

	private void handlePrivmsg(IRCCommand cmd) {
		if (client.containsChannel(cmd.getParameter(0))) {
			client.printToChannel(cmd.getParameter(0), formatPrivmsg(cmd));
		} else if (cmd.getParameter(0).equals(client.getNick())){
			client.printToPrivmsg(cmd.getNick(), formatPrivmsg(cmd));
		}
		else {
			client.printToPrivmsg(cmd.getParameter(0), formatPrivmsg(cmd));
		}
	}
	
	private void handlePing(IRCCommand cmd) {
		client.commandc.pong(cmd.getParameter(0));
	}
	
	private void handleJoin(IRCCommand cmd) {
		client.printToSys(cmd.getString());
		if (cmd.getNick().equals(client.getNick())){
			client.addChannel(cmd.getParameter(0));
		}
		else {
			client.addUser(cmd.getParameter(0), cmd.getNick());
			client.printToChannel(cmd.getParameter(0), formatJoin(cmd));
		}
	}
	
	private void handlePart(IRCCommand cmd) {
		client.removeUser(cmd.getParameter(0), cmd.getNick());
		client.printToChannel(cmd.getParameter(0), formatPart(cmd));
	}
	
	private void handleNamelist(IRCCommand cmd) {
		String[] users = cmd.getParameter(3).split(" ");
		for (int i = 0;i < users.length ; i++){
			client.addUser(cmd.getParameter(2), users[i]);
		}
	}
	

	
	private String formatPrivmsg(IRCCommand cmd){
		return "<" + cmd.getNick() + "> " + cmd.getParameter(1);
	}
	
	private String formatJoin(IRCCommand cmd) {
		return formatNotification(cmd.getNick() + "(" + cmd.getPrefix() + ") has joined " + cmd.getParameter(0));
	}
	
	private String formatNotification(String s) {
		return "* " + s;
	}
	
	private String formatPart(IRCCommand cmd) {
		String msg = null;
		if (cmd.getParameter(1) != null) {
			msg = " (" + cmd.getParameter(1) + ")";
		}
		return formatNotification(cmd.getNick() + " has left " + cmd.getParameter(0) + msg);
	}
	
	private String formatKick(IRCCommand cmd) {
		return cmd.getParameter(1) + " was kicked by " + cmd.getNick() + ": " + cmd.getParameter(2);
	}
	
	private String formatTopic(IRCCommand cmd) {
		return formatNotification(cmd.getNick() + " changed the topic to: " + cmd.getParameter(1));
	}
	
	private String format332(IRCCommand cmd) {
		return formatNotification("The topic is: " + cmd.getParameter(2));
	}
	
	private String formatQuit(IRCCommand cmd) {
		return formatNotification(cmd.getNick() + " just quit: " + cmd.getParameter(0));
	}
	
	private String formatWelcome(IRCCommand cmd) {
		return cmd.getCommand() + ": " + cmd.getParameter(1);
	}
	
	private String formatMode(IRCCommand cmd) {
		return "";
	}
	
	
	private void parseMode(IRCCommand cmd) {
		int parameter = 0;
		boolean sign = true;
		String modes = cmd.getParameter(1);
		for (int i = 0; i < modes.length(); i++){
			char c = modes.charAt(i);
			if (c == '+'){
				sign = true;
			}else if (c == '-'){
				sign = false;
			}else if (c == 'o' || c == 'O' || c == 'v'){
				client.changeOpVoice(cmd.getParameter(0), cmd.getParameter(parameter + 2), c, sign);
				parameter++;
			}else if (c == 'k' || c == 'l' ||c == 'b' ||c == 'e' ||c == 'I'){
				parameter++;
			}
		}
	}

}
